home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1997 March
/
CHIP Mart 1997.iso
/
prg
/
CHKIO
/
CHKIO.BAS
< prev
next >
Wrap
BASIC Source File
|
1996-06-05
|
28KB
|
1,024 lines
'--------------------------------------------------------------------
' Title : CheckIOPorts
' Version : 1.32
' Author : PhG
' Overview : try and locate I/O ports
' Future : no! ;-)
' Notes : Special thanks to Jean-Claude Gaertner and Rick Harris
' who kindly devoted some of their precious time in order
' to have a look at this small utility!
' Usage : CHKIO <options> [ > redirectionFile ]
'
' Who When What
' --- -------- ------------------------------------------------------
' PhG 06-06-96 v1.32 corrected a discrepancy between doc and help screen ;
' a beep as another warning ; and for safety, removed the
' possibility for the TSR to run from swapfile, i.e. 350 Kb
' of free EMS are not available then bye! ;-)
' PhG 05-27-96 v1.31
' PhG 05-26-96 v1.3 added default exclude, warning message, forced reboot
' PhG 04-23-96 v1.2 fixed a typo in help, code frozen, no future!
' PhG 04-17-96 v1.12 corrects a silly change which prevented v1.11 from
' working while v1.10 did! (zmethod -> method)
' v1.11 defaults to $200..$3FF for FREE and USED commands
' removed default values which were passed to TSR
' (firstval, etc.)
' PhG 04-15-96 v1.1 program created from CHKPORTS v1.0 Modula-2 code
'--------------------------------------------------------------------
$CPU 8086 ' for old XTs!
$OPTIMIZE SIZE
$COMPILE EXE
$DEBUG MAP OFF
$DEBUG PBDEBUG OFF
$LIB COM OFF
$LIB CGA OFF
$LIB EGA OFF
$LIB VGA OFF
$LIB HERC OFF
$LIB LPT OFF
$LIB IPRINT OFF
$LIB FULLFLOAT OFF
$ERROR BOUNDS OFF
$ERROR NUMERIC OFF
$ERROR OVERFLOW OFF
$ERROR STACK OFF
$FLOAT PROCEDURE
$COM 0
$STRING 1 ' 1K strings is enough here
$STACK 2048
$SOUND 1
$DIM ARRAY
$DYNAMIC
$OPTION CNTLBREAK OFF
'--------------------------------------------------------------------
DEFINT A-Z
OPTION ARRAY BASE 0
OPTION BINARY BASE 0
%False = 0
%True = NOT %False
%Dummy = %true
'--------------------------------------------------------------------
' externals
' you'll have to supply your own functions if you want to recompile!
$LINK "SKYTOOLS.PBU"
$INCLUDE "C:\ASTRO\SKYTOOLS.DEF"
$INCLUDE "C:\PB\SRC\REGNAMES.BAS"
DECLARE SUB GetStrLoc() ' PB 3.1 runtime routine for locating strings
'--------------------------------------------------------------------
' error handling
%eNone = 100
%eUsage = 101
%eDosTooOld = 102
%eBadExeName= 103
%eTooMany = 104
%eTooManyParms=105
%ejoker = 106
%ebadfilename=107
%ebakpb = 108
%ebadnumber = 109
%ebadrangeio = 110
%emissingparms=111
%ebadcount = 112
%ebadext = 113
%ealreadyloaded=114
%eneeded=115
%enotloaded = 116
%enotyettsr = 117
%ecantunloadfull = 118
%ebadrangetick = 119
%eAborted=120
%eEMSneeded=121
'--------------------------------------------------------------------
' constants
%MinDosVersion = 310 ' 3.10 or later
%cmdNone = &HFF
%cmdInstallTSR = &H00
%cmdReport = &h01
%cmdReset = &h02
%cmdStatus = &H03
%cmdUnload = &H04
%cmdScanPort= &H05
%cmdFree = &H06
%cmdUsed = &H07
%rcWasHere = &H08
%idAX = &HDADB
%idDX = &HFBFA
%idFooBar = &HFFFF
%Multiplex = &H2F
%PopMultiplex = 16
%PopTimer = 4
%Dos = &H21
%hi = &H100
%EMSPage = &H4000
%EMS = &H67
%OneK = &H400
%MemGrab = &HA0000
%MemUse = &H2000
%NeededEMS = 350000 ' 160 Kb needed but for sure...
%NeededDisk = 350000 ' &H7FFFFFFF force EMS only - disk swapping+timer sucks
%MinPopInterval = 1 ' unit = 1/18.2s
%MaxPopInterval = 1820 ' 100 seconds ?
%defaultcount = 16
%emptyB = &HFF
%EmptyW = &HFFFF ' unused here (was when checking for a word value p,p+1)
%FirstPort = &H0000
%LastPort = &H03FF
%DefaultFirstPort = &h0200 ' better safe than sorry
%firstHD = &h0320 ' hard disk controller
%lastHD = &h032F
%firstFD = &h03F0 ' floppy disk controller
%lastFD = &h03F7
'--------------------------------------------------------------------
%portnotyettested = 0
%portusedonce = 1
%portfreetillnow = 2
' global array
DIM STATIC IOport (%FirstPort:%LastPort) ' compile time
SHARED IOport()
'--------------------------------------------------------------------
' global variables
SHARED Programname$,Exename$,Version$,Copyright$,Swapfilename$
SHARED Defaultext$,Defaultbak$,Banner$
SHARED firstval,lastval,Reportfile$ ' in case TSR would be funny
SHARED Begtime$
SHARED method
'--------------------------------------------------------------------
Programname$ = "Q&D CheckIOPorts"
Exename$ = "CHKIO"
Version$ = "v1.32"
Copyright$ = "(c) PhG 1996"
Swapfilename$= "~CHKIO.TMP" ' no longer possible for safety
Defaultext$ = "RPT"
Defaultbak$ = "BAK"
Banner$=Programname$+" "+Version$+" "+Copyright$
'
ON ERROR GOTO Abort
GOTO Start: ' jump to main() ;-)
'--------------------------------------------------------------------
Abort:
IF ERR = %eUsage THEN
PRINT Banner$
PRINT
PRINT "Syntax: '";Exename$;" <options> [>file]', where options (without / or -) are:"
PRINT
PRINT "- <port> [count] checks 'count' I/O ports starting from 'port'"
PRINT " 'port' belongs to the [$0000..$03FF] range, 'count' default value is 16"
PRINT " Values are given in decimal, unless they begin with a '$' for hexadecimal"
PRINT "- FREE shows the most probably unused I/O ports in the [$0200..$03FF] range"
PRINT "- USED shows the most probably used I/O ports in the [$0200..$03FF] range"
PRINT "- SAMPLE <ticks> <port> [count] install program as a TSR"
PRINT " 'ticks' is the sampling frequency (one tick is 1/18.2s)"
PRINT "- RESET reinitializes results got from TSR"
PRINT "- REPORT dumps current results to ";Exename$;".";Defaultext$;" file"
PRINT " Previous file of same name is kept as ";exename$;".";Defaultbak$
PRINT "- STATUS shows current TSR status"
PRINT "- UNLOAD tries and unloads program from memory"
PRINT
PRINT "For SAFETY, FREE and USED commands do NOT test hard disk and floppy I/O ports."
PRINT "Program can *try* 4 methods to check whether I/O ports are used or not."
PRINT "To specify survey method, enter M0, M1, M2 or M3 as the *first* parameter."
PRINT "Default is M0. Beware: once program is TSR, you CANNOT change survey method!"
PRINT
PRINT "Special thanks to Jean-Claude Gaertner and Rick Harris who kindly devoted"
PRINT "some of their precious time in order to have a look at this small utility!";
END %eUsage-%eNone
END IF
SELECT CASE ERR
CASE %eUsage
E$="How can such things be?"
CASE %eDosTooOld
E$="DOS version should be 3.1 or later"
CASE %eBadExeName
E$="Executable name was changed"
CASE %eToomany
E$="At least one option repeated needlessly"
CASE %etoomanyparms
E$="Too many parameters in command line"
CASE %ejoker
E$="No joker allowed in filename"
CASE %ebadfilename
E$="Illegal filename"
CASE %ebakpb
E$="Problem while trying to create backup copy of report"
CASE %ebadnumber
E$="Illegal number or command" ' mispelled cmd goes there!
CASE %ebadrangeio
E$="I/O port address should be in the [$0000..$03FF] range"
CASE %emissingparms
E$="Missing parameter(s)"
CASE %ebadcount
E$="Bad I/O port interval"
CASE %ebadext
E$="Report cannot have backup extension"
CASE %ealreadyloaded
E$="Program already installed"
CASE %eneeded
E$="Not enough space for swap area (EMS or disk)"
CASE %enotloaded
E$="Nonsense, for program is not in memory"
CASE %enotyettsr
E$="Nonsense, for program is not in memory"
CASE %eCantUnloadFull
E$= "6 KB lost in memory, for uninstall could not be fully completed"
E$= E$+CHR$(13)+CHR$(10)
CASE %ebadrangetick
E$="Ticks should be in the [1..1820] range"
CASE %eAborted
E$="Execution cancelled"
CASE %eEMSneeded
E$="Not enough EMS free for swap area (about 350 Kb needed)"
CASE ELSE
E$=HEX$(ERADR) ' ERADR is a longint (7fFFffFF)
h$="00000000"
padcount=len(h$)-len(e$)
hexa$=MID$(h$,1,padcount)
e$=hexa$+E$
E$= "Error #"+MID$(STR$(ERR),2)+" at address $"+E$
END SELECT
E$=Programname$+": "+E$+"!"
PRINT E$;
END ERR-%eNone
'--------------------------------------------------------------------
SUB StdOut ( BYVAL Text AS STRING )
! push DS ; save DS FOR PowerBASIC
! push WORD Ptr Text ; push STRING handle ON stack
! CALL GetStrLoc
! jcxz ExitStdOut
! mov DS, DX
! mov DX, AX
! mov AH, &H40 ; DOS WRITE TO file
! mov BX, 1 ; file handle 1 is CONS
! INT &H21
ExitStdOut:
! pop DS
END SUB
SUB StdOutLn( BYVAL Text AS STRING )
StdOut Text$ + CHR$(13, 10)
END SUB
'--------------------------------------------------------------------
'
FUNCTION EMSHere
REG %AX, &H35*%hi+&H67 ' get int 67h address
CALL INTERRUPT %Dos
Driversegment??=REG(%ES)
DEF SEG = Driversegment??
Drivername$=PEEK$(&H00+&H0A,8) ' name at offset $0A
DEF SEG
IF Drivername$="EMMXXXX0" THEN
EMSHere = %True
ELSE
EMSHere = %False
END IF
END FUNCTION
'
FUNCTION EMSOK
REG %AX , &H40*%hi ' get status
CALL INTERRUPT %EMS
Rc?? = REG(%AX)
IF (Rc?? \ %hi) = &H00 THEN
EMSOK = %True
ELSE
EMSOK = %False
END IF
END FUNCTION
'
FUNCTION Getfreeems???
IF EMSHere = %True THEN
IF EMSOK = %True THEN
REG %AX , &H42*%hi ' get # of pages
CALL INTERRUPT %EMS
Rc?? = REG(%AX)
IF (rc \ %hi) = &H00 THEN
Getfreeems??? = REG(%BX) * %EMSPage
ELSE
Getfreeems??? = 0
END IF
END IF
END IF
END FUNCTION
'
FUNCTION Getmyfreespace???(BYVAL drive) ' 1=A:, 3=C:, 4=D:
REG(%DX),drive
REG(%AX),&H36*%hi
CALL INTERRUPT %Dos
SectorsPerCluster = REG(%AX)
IF SectorsPerCluster = &HFFFF THEN ' drive does not exist
Getmyfreespace???=0
ELSE
FreeClusters=REG(%BX)
BytesPerSector = REG(%CX)
Free???=SectorsPerCluster*FreeClusters*BytesPerSector
Getmyfreespace???=Free???
END IF
END FUNCTION
'
SUB BuildSwapPath (BYVAL Swp$,P$,Free???)
T$=Upper$(ENVIRON$("TMP"))
IF T$="" THEN
T$=Upper$(ENVIRON$("TEMP"))
END IF
IF T$="" THEN
n=3
P$="C:\"
ELSE
IF RIGHT$(T$,1) <> "\" THEN
T$=T$+"\"
END IF
IF MID$(T$,2,2) = ":\" THEN
n = ASC(LEFT$(T$,1))-ASC("A")+1
P$=T$
ELSE
n=3
P$="C:\"
END IF
END IF
P$=P$+Swp$
Free???=Getmyfreespace???(n)
END SUB
'--------------------------------------------------------------------
SUB ShowBanner(BYVAL ticks, BYVAL firstval, BYVAL lastval, BYVAL flagEMS, BYVAL Swappath$)
PRINT Banner$
PRINT
PRINT "TSR Swap area : ";
IF flagEMS = %true THEN
PRINT "EMS memory"
ELSE
PRINT Swappath$;" file"
PRINT " (very BAD idea... unless you use a RAM disk)"
END IF
IF firstval=lastval THEN
PRINT "Sampled I/O address: $"; Padhex$(firstval,4)
ELSE
PRINT "Sampled I/O range : [$"; Padhex$(firstval,4);
PRINT "..$";Padhex$(lastval,4);"]"
END IF
S$=MID$(STR$(ticks),2)
PRINT "Sampling fréquency : every ";S$;" tick";
IF ticks> 1 THEN PRINT "s";
PRINT " (one tick is 1/18.2s)"
END SUB
'--------------------------------------------------------------------
FUNCTION getnumber(BYVAL V$,Value&)
SELECT CASE LEFT$(V$,1)
CASE "$"
V$=MID$(V$,2)
IF VERIFY (V$,"0123456789ABCDEF") > 0 THEN
getnumber=%false
EXIT FUNCTION
END IF
' $FFFFffff is safe maximum so check overflow
IF LEN(V$) > 8 THEN
getnumber=%false
EXIT FUNCTION
END IF
H$="&H0"+V$
A???=VAL(H$)
IF A??? < 2147483648 THEN
N&=A???
ELSE
N&=VAL("&H"+V$)
END IF
CASE ELSE
IF VERIFY (V$,"0123456789") > 0 THEN
getnumber=%false
EXIT FUNCTION
END IF
N&=VAL(V$)
END SELECT
Value&=N&
getnumber=%true
END FUNCTION
FUNCTION chkrange(V&,First&,Last&)
IF V& < First& OR V& > Last& THEN
chkrange=%false
ELSE
chkrange=%true
END IF
END FUNCTION
FUNCTION parmtoval (BYVAL Cli$,BYVAL n)
V$=Argv$(Cli$,n)
IF getnumber(V$,V&)=%false THEN ERROR %ebadnumber
IF chkrange(V&,%firstport,%lastport)=%false THEN ERROR %ebadrangeio
parmtoval=V&
END FUNCTION
'--------------------------------------------------------------------
SUB ParseCLI (cmd,zticks,zfirstval,zlastval,Reportfile$,zmethod)
Cli$=Upper$(COMMAND$)
argcount=argc(Cli$)
IF argcount=0 THEN ERROR %eusage
foundSOSarg=FindArg(Cli$,"?|H|HELP|SOS",%False)
foundSOSopt=FindOpt(Cli$,"?|H|HELP|SOS",%False)
SELECT CASE (foundSOSarg+foundSOSopt)
CASE 0
' no help call
CASE 1
ERROR %eUsage
CASE ELSE
ERROR %eTooMany
END SELECT
' init defaults here even when not needed
cmd = %cmdNone
zticks = %minPopInterval
zfirstval= %defaultfirstport
zlastval = %lastport
Reportfile$=Exename$+"."+Defaultext$
zmethod = 0 ' default method
patch=%true
SELECT CASE Argv$(Cli$,1)
CASE "M0"
zmethod=0
CASE "M1"
zmethod=1
CASE "M2"
zmethod=2
CASE "M3"
zmethod=3
CASE ELSE
patch=%false
END SELECT
IF patch=%true THEN
Newcli$=""
FOR i=2 TO argcount
Newcli$=Newcli$+" "+Argv$(Cli$,i)
NEXT
Cli$=Newcli$
DECR argcount
END IF
SELECT CASE Argv$(Cli$,1)
CASE "FREE"
IF argcount > 1 THEN ERROR %etoomanyparms
cmd=%cmdFree
CASE "USED"
IF argcount > 1 THEN ERROR %etoomanyparms
cmd=%cmdUsed
CASE "SAMPLE","TSR","S"
IF argcount > 4 THEN ERROR %etoomanyparms
IF argcount < 3 THEN ERROR %emissingparms
V$=Argv$(Cli$,2)
IF getnumber(V$,V&)=%false THEN ERROR %ebadnumber
IF chkrange(V&,%minpopinterval,%maxpopinterval)=%false THEN ERROR %ebadrangetick
zticks=V&
zfirstval=parmtoval(Cli$,3)
SELECT CASE argcount
CASE 3
zcount=%defaultcount
CASE ELSE
zcount=parmtoval(Cli$,4)
END SELECT
zlastval=zfirstval+zcount-1
IF zlastval < zfirstval THEN ERROR %ebadcount
cmd=%cmdInstallTSR
CASE "REPORT","RPT","R"
SELECT CASE argcount
CASE 1
' already set
$IF 0
CASE 2 ' useless for we cannot change TSR variables this way!
F$=Argv$(Cli$,2)
IF INSTR(F$,ANY "*?") > 0 THEN ERROR %eJoker
IF INSTR(F$,".")=0 THEN F$=F$+"."+Defaultext$
IF TALLY(F$,".") > 1 THEN ERROR %ebadfilename
CALL SplitPath(F$,Fcurrunit$,Fcurrpath$,Fcurrfile$)
CALL SplitName(Fcurrfile$,F8$,F3$)
IF F3$=Defaultbak$ THEN ERROR %ebadext
Reportfile$=F$
$ENDIF
CASE ELSE
ERROR %etoomanyparms
END SELECT
IF exist(Reportfile$)=%true THEN
rc=makebak(Reportfile$,Defaultbak$)
IF rc=%false THEN ERROR %ebakpb
END IF
cmd=%cmdReport
CASE "RESET","RST","Z"
IF argcount > 1 THEN ERROR %etoomanyparms
cmd=%cmdReset
CASE "STATUS","I"
IF argcount > 1 THEN ERROR %etoomanyparms
cmd=%cmdStatus
CASE "UNLOAD","U"
IF argcount > 1 THEN ERROR %etoomanyparms
cmd=%cmdUnload
CASE ELSE
IF argcount > 2 THEN ERROR %etoomanyparms
zfirstval=parmtoval(Cli$,1)
SELECT CASE argcount
CASE 1
zcount=%defaultcount
CASE ELSE
zcount=parmtoval(Cli$,2)
END SELECT
zlastval=zfirstval+zcount-1
IF zlastval < zfirstval THEN ERROR %ebadcount
cmd=%cmdScanPort
END SELECT
END SUB
'--------------------------------------------------------------------
' SUB resetarray (BYVAL firstval,BYVAL lastval)
' FOR i = firstval TO lastval
' ioport(i)=%portnotyettested
' NEXT
' END SUB
SUB reportarray(BYVAL firstval,BYVAL lastval,BYVAL F$)
hnd=FREEFILE
OPEN "o",#hnd,F$
FOR i = firstval TO lastval
S$="I/O port $"+Padhex$(i,4)
SELECT CASE ioport(i)
CASE %portnotyettested
T$=" has not been tested YET: how did you get here? ;-)"
CASE %portfreetillnow
T$=" is probably free"
CASE %portusedonce
T$=" is probably NOT free"
END SELECT
S$=S$+T$
PRINT #hnd,S$
PRINT S$
NEXT
CLOSE #hnd
END SUB
'--------------------------------------------------------------------
FUNCTION Padhex$ (BYVAL v,BYVAL padcount)
Padstr$ = "0000000000000000" ' 16 digits
padcount = padcount MOD 16 ' better safe than sorry!
S$=HEX$(v)
Padhex$=MID$(Padstr$,1,padcount-LEN(S$))+S$
END FUNCTION
SUB ShowIOport (BYVAL io,BYVAL vlo,BYVAL vhi)
S$="I/O port $"+Padhex$(io,4)
IF isfree(vlo,vhi)=%true THEN
S$=S$+" is probably free ($"
ELSE
S$=S$+" is probably NOT free ($"
END IF
S$=S$+Padhex$(vhi,2)
S$=S$+Padhex$(vlo,2)
S$=S$+")"
CALL StdOutLn (S$) ' allow redirecting output to file
END SUB
SUB SkipIOport (BYVAL io)
S$="I/O port $"+Padhex$(io,4)
S$=S$+" was *not* tested, for safety"
CALL StdOutLn (S$) ' allow redirecting output to file
END SUB
'--------------------------------------------------------------------
' INP method
' 0 = read port, port+1 and check if %empty
' 1 = read port, port+1 and check if values differ from one another
' 2 = read port, port and check if %empty
' 3 = read port, port and check if values differ from one another
' method 0 seems best, or 2 perhaps. 3 is a no-no.
SUB readport (BYVAL i,vlo,vhi)
SELECT CASE method
CASE 0,1
vlo=INP(i)
vhi=INP(i+1)
CASE 2,3
vlo=INP(i)
vhi=INP(i)
END SELECT
END SUB
FUNCTION isfree (BYVAL vlo, BYVAL vhi)
rc=%false
SELECT CASE method
CASE 0,2
IF ( (vlo=%emptyb) AND (vhi=%emptyb) ) THEN rc=%true
CASE 1,3
IF vlo = vhi THEN rc=%true
END SELECT
isfree=rc
END FUNCTION
'--------------------------------------------------------------------
$if %dummy
SUB MyBeep
SOUND 444,2
SOUND 222,2
END SUB
FUNCTION GoOnAfterWarning
rc=%False
PRINT
RESTORE Warning
DO
READ s$
IF s$="*" THEN EXIT LOOP
PRINT s$
LOOP
ok$="yES"
prompt$="Enter ["+ok$+"] (y, E, S) if you *really* want to go on:"
PRINT
PRINT prompt$;
CALL MyBeep
INPUT " ",s$
PRINT
s$=RTRIM$(LTRIM$(s$))
IF s$=ok$ THEN rc=%True
GoOnAfterWarning=rc
Warning:
DATA "****************************************************************"
DATA "* Warning!!! Think twice before you run this program! *"
DATA "* In your own interest, be sure you have fully read CHKIO's *"
DATA "* documentation *before* you proceed, for running this program *"
DATA "* without knowing what it is about is definitely *not* wise! *"
DATA "* This warning is all the more important with TSR option! *"
DATA "****************************************************************"
DATA "*"
END FUNCTION
FUNCTION RebootAfterWarning
rc=%True
PRINT
RESTORE PleaseReboot
DO
READ s$
IF s$="*" THEN EXIT LOOP
PRINT s$
LOOP
ok$="yES"
prompt$="Enter ["+ok$+"] (y, E, S) if you *really* want to exit to DOS:"
PRINT
PRINT prompt$;
CALL MyBeep
INPUT " ",s$
PRINT
s$=RTRIM$(LTRIM$(s$))
IF s$=ok$ THEN rc=%False
RebootAfterWarning=rc
PleaseReboot:
DATA "****************************************************************"
DATA "* Warning!!! Think twice before you exit this program! *"
DATA "* Whatever I/O ports have been tested, you definitely should *"
DATA "* turn you PC off then on again! At any case, you'd better *"
DATA "* not exit to DOS now but reboot your system instead! *"
DATA "****************************************************************"
DATA "*"
END FUNCTION
$else
FUNCTION GoOnAfterWarning
rc=%true
GoOnAfterWarning=rc
END FUNCTION
FUNCTION RebootAfterWarning
rc=%false
RebootAfterWarning=rc
END FUNCTION
$endif
SUB ChkReboot
IF RebootAfterWarning = %True THEN
PRINT "********************************************************"
PRINT "* System is now willingly lost in an infinite loop! *"
PRINT "* Either reboot with Ctrl-Alt-Del or the Reset button! *"
PRINT "* Even better, turn your PC off then on again! *"
PRINT "********************************************************"
DO
LOOP
END IF
END SUB
SUB ChkHdRisk(BYVAL p1, BYVAL p2)
match=0
FOR i = p1 to p2
SELECT CASE i
CASE %firstHD TO %lastHD, %firstFD TO %lastFD
incr match
END SELECT
NEXT
if match > 0 then
PRINT "***********************************************************"
PRINT "* Warning!!! Specified range include dangerous addresses! *"
PRINT "* (i.e. hard disk and/or floppy disk controllers) *"
PRINT "***********************************************************"
end if
END SUB
'--------------------------------------------------------------------
' main()
Start:
IF DosVersion < %minDosVersion THEN ERROR %eDosTooOld
Exepath$= Getarg0$
Exepath$= Upper$(Exepath$)
CALL SplitPath(Exepath$,Currunit$,Currpath$,Currfile$)
CALL SplitName(Currfile$,Filename$,Ext$)
IF Filename$ <> Exename$ THEN ERROR %eBadExeName
CALL ParseCLI (cmd,zticks,zfirstval,zlastval,Reportfile$,zmethod)
' was a CALL resetarray (firstval, lastval)
FOR i = zfirstval TO zlastval
ioport(i)=%portnotyettested
NEXT
SELECT CASE cmd
CASE %cmdInstallTSR
REG %AX,%idAX
REG %DX,%idDX
REG %BX,%cmdInstallTSR
CALL INTERRUPT %Multiplex
IF NOT (REG(%AX) = %idAX AND REG(%DX) = %idDX AND REG(%BX) = %cmdInstallTSR) THEN
ERROR %eAlreadyLoaded
END IF
CALL BuildSwapPath(Swapfilename$,Swappath$,Freedisk???)
Freeems??? = Getfreeems??? ' 0 if none or if error
FlagEMS = %True
IF Freeems??? < %NeededEMS THEN
FlagEMS = %False
' IF Freedisk??? < %NeededDisk THEN ERROR %eNeeded
' no longer allow swapfile, we abort here
ERROR %eEMSNeeded
END IF
CALL ChkHdRisk (zfirstval,zlastval)
IF GoOnAfterWarning=%False THEN ERROR %eAborted
ticks=zticks
firstval=zfirstval
lastval=zlastval
method=zmethod
CALL ShowBanner(ticks,firstval,lastval,flagEMS,Swappath$)
X??? = SETMEM(-%MemGrab)
X??? = SETMEM(%MemUse)
POPUP MULTIPLEX %idAX, %idDX
POPUP TIMER ticks
POPUP SLEEP USING EMS,Swappath$ ' need about 200 Kb
Begtime$=TIME$
' in fact one should not try using EMS if FlagEMS is false but... ;-)
DO
popmethod = POPUP(4)
SELECT CASE popmethod
CASE %PopMultiplex
cmd = REG(%BX)
SELECT CASE cmd
CASE %cmdReport
REG %AX, %idAX
REG %DX, %idDX
REG %BX, %rcWasHere
CALL reportarray (firstval,lastval,Reportfile$)
CASE %cmdReset
REG %AX, %idAX
REG %DX, %idDX
REG %BX, %rcWasHere
' was a CALL resetarray (firstval,lastval)
FOR i = firstval TO lastval
ioport(i)=%portnotyettested
?".";
NEXT
PRINT "Reset done!"
CASE %cmdStatus
REG %AX, %idAX
REG %DX, %idDX
REG %BX, %rcWasHere
CALL ShowBanner(ticks,firstval,lastval,flagEMS,Swappath$)
PRINT "Install time : ";BegTime$ ' same length
PRINT "Current time : ";TIME$
CASE %cmdInstallTSR
REG %AX, %idAX
REG %DX, %idDX
REG %BX, %rcWasHere
CASE %cmdUnload
REG %AX, %idAX
REG %DX, %idDX
REG %BX, %rcWasHere
' message MUST be HERE !
PRINT "Uninstalling ";Programname$;"..."
' if END here, TSR is desactivated but...
' 6 KB remain lost and vectors remain hooked so...
Retry = 0
POPUP TIMER 9 ' every 0.5 s try at most 10 times (2 now)
DO WHILE Retry < 2
POPUP SLEEP
IF POPUP(1) <> %False THEN
' message no longer here for must be before retries
POPUP TIMER OFF
CALL ChkReboot
END %eNone-%eNone
END IF
INCR Retry
LOOP
' cannot end here with POPUP STUFF a CR nor ERROR % !!! so...
POPUP TIMER OFF
BEEP
CALL ChkReboot
END %eCantUnloadFull-%eNone
END SELECT
CASE %PopTimer
' perform sampling here
FOR i = firstval TO lastval
CALL readport (i,vlo,vhi)
was=IOport(i)
SELECT CASE isfree(vlo,vhi)
CASE %true
SELECT CASE was
CASE %portnotyettested
IOport(i)=%portfreetillnow
END SELECT
CASE %false
SELECT CASE was
CASE %portnotyettested,%portfreetillnow
IOport(i)=%portusedonce
END SELECT
END SELECT
NEXT
END SELECT
POPUP SLEEP
LOOP
CASE %cmdReport
REG %AX,%idAX
REG %DX,%idDX
REG %BX,%cmdReport
CALL INTERRUPT %Multiplex
IF (REG(%AX) = %idAX AND REG(%DX) = %idDX AND REG(%BX) = %cmdReport) THEN
ERROR %eNotYetTSR
END IF
' report must be in TSR code
CASE %cmdReset
REG %AX,%idAX
REG %DX,%idDX
REG %BX,%cmdReset
CALL INTERRUPT %Multiplex
IF (REG(%AX) = %idAX AND REG(%DX) = %idDX AND REG(%BX) = %cmdReset) THEN
ERROR %eNotYetTSR
END IF
' reset must be in TSR code
CASE %cmdStatus
REG %AX,%idAX
REG %DX,%idDX
REG %BX,%cmdStatus
CALL INTERRUPT %Multiplex
IF (REG(%AX) = %idAX AND REG(%DX) = %idDX AND REG(%BX) = %cmdStatus) THEN
ERROR %eNotYetTSR
END IF
' display must be in TSR code
CASE %cmdUnload
REG %AX,%idAX
REG %DX,%idDX
REG %BX,%cmdUnload
CALL INTERRUPT %Multiplex
IF (REG(%AX) = %idAX AND REG(%DX) = %idDX AND REG(%BX) = %cmdUnload) THEN
ERROR %eNotLoaded
END IF
CASE %cmdScanPort
' should be okay
CALL ChkHdRisk (zfirstval,zlastval)
IF GoOnAfterWarning=%False THEN ERROR %eAborted
method=zmethod
FOR i = zfirstval TO zlastval
CALL readport (i,vlo,vhi)
CALL showioport(i,vlo,vhi)
NEXT
CASE %cmdFree
IF GoOnAfterWarning=%False THEN ERROR %eAborted
method=zmethod
FOR i = zfirstval TO zlastval
SELECT CASE i
CASE %firstHD TO %lastHD
CALL SkipIOport(i)
CASE %firstFD TO %lastFD
CALL SkipIOport(i)
CASE ELSE
CALL readport (i,vlo,vhi)
IF isfree(vlo,vhi)=%true THEN CALL showioport(i,vlo,vhi)
END SELECT
NEXT
CASE %cmdUsed
IF GoOnAfterWarning=%False THEN ERROR %eAborted
method=zmethod
FOR i = zfirstval TO zlastval
SELECT CASE i
CASE %firstHD TO %lastHD
CALL SkipIOport(i)
CASE %firstFD TO %lastFD
CALL SkipIOport(i)
CASE ELSE
CALL readport (i,vlo,vhi)
IF isfree(vlo,vhi)=%false THEN CALL showioport(i,vlo,vhi)
END SELECT
NEXT
END SELECT
SELECT CASE cmd
CASE %cmdScanPort,%cmdFree,%cmdUsed
CALL ChkReboot
END SELECT
END %eNone-%eNone